#include "querys_answer.h"
#include "../main/main_querys.h"
#include "../main/map_querys.h"
#include "../commons/drugs.h"
#include "../io/print.h"

void demarshal_send_min(void* parameters, void** ans, int* ans_size){
	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= set_if_min(*(int*)parameters);
}

void demarshal_get_min(void* parameters, void** ans, int* ans_size){
	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= get_min();
}



void demarshal_add_aeroplane_to_print(void* parameters, void** ans, int* ans_size){
	int ciudad_id = *(int*)parameters;
	parameters += sizeof(int);

	int distace = *((int*)parameters);
	parameters+=sizeof(int);

	int drugs_cant = *((int*)parameters);
	parameters+=sizeof(int);

	droga_t* drugs= malloc(sizeof(int) * drugs_cant);
	int i;
	for(i=0 ; i<drugs_cant ; i++){
		drugs[i]=malloc(sizeof(struct st_droga_t));
		drugs[i]->nombre=malloc(strlen(parameters) + 1);
		strcpy(drugs[i]->nombre,parameters);
		parameters += strlen(parameters) + 1;

		drugs[i]->cant=*((int*)parameters);
		parameters+=sizeof(int);
	}

	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= add_aeroplane_to_print(ciudad_id, distace, drugs_cant, drugs);
}

void demarshal_ready_to_draw(void* parameters, void** ans, int* ans_size){
	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= ready_to_draw();
}

void demarshal_throw_medication(void* parameters, void** ans, int* ans_size){
	int ciudad_id = *(int*)parameters;
	parameters += sizeof(int)*2;

	int drugs_cant = *((int*)parameters);
	parameters+=sizeof(int);

	droga_t drugs= malloc(sizeof(struct st_droga_t) * drugs_cant);
	int i;
	for(i=0 ; i<drugs_cant ; i++){
		drugs[i].nombre=parameters;
		parameters += strlen(parameters) + 1;

		drugs[i].cant=*((int*)parameters);
		parameters+=sizeof(int);
	}

	throw_medication(ciudad_id, drugs_cant, drugs);
	*ans_size= drugs_cant * sizeof(int);
	*ans= malloc(*ans_size);
	char* ansp= *ans;
	for(i=0 ; i<drugs_cant ; i++){
		*((int*)ansp)=drugs[i].cant;
		ansp+=sizeof(int);
	}
	free(drugs);

}

void demarshal_get_city_id(void* parameters, void** ans, int* ans_size){
	*ans_size=sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)=get_city_id(parameters);
}

void demarshal_get_neighbours(void* parameters, void** ans, int* ans_size){
	int * neighbours;
	*ans_size = get_neighbours(&neighbours,*(int*)parameters)*sizeof(int);
	*ans= malloc(*ans_size);
	memcpy(*ans,neighbours,*ans_size);
}

void demarshal_needs(void* parameters, void** ans, int* ans_size){
	int city_id = *(int*)parameters;
	parameters += sizeof(int);

	int drugs_cant = *((int*)parameters);
	parameters+=sizeof(int);

	droga_t* drugs= malloc(sizeof(int) * drugs_cant);
	int i;
	for(i=0 ; i<drugs_cant ; i++){
		drugs[i]=malloc(sizeof(struct st_droga_t));
		drugs[i]->nombre=parameters;
		parameters += strlen(parameters) + 1;

		drugs[i]->cant=*((int*)parameters);
		parameters+=sizeof(int);
	}
	
	*ans_size=sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)=needs(city_id, drugs_cant, drugs);
	for(i=0 ; i<drugs_cant ; i++){
		free(drugs[i]);
	}
	free(drugs);
}

void demarshal_null_drugs_demand(void* parameters, void** ans, int* ans_size){
	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= null_drugs_demand();
}

void demarshal_close_main(void* parameters, void** ans, int* ans_size){
	free(parameters-sizeof(int));
	close_main(0);
}

void demarshal_get_city_cant(void* parameters, void** ans, int* ans_size){
	*ans_size= sizeof(int);
	*ans= malloc(*ans_size);
	*((int*)*ans)= get_city_cant();
}

void marshaling_init(){
	add_query(SEND_MIN, demarshal_send_min);
	add_query(GET_MIN, demarshal_get_min);
	add_query(ADD_AEROPLANE_TO_PRINT,demarshal_add_aeroplane_to_print);
	add_query(READY_TO_DRAW, demarshal_ready_to_draw);
	add_query(THROW_MEDICATION,demarshal_throw_medication);
	add_query(GET_CITY_ID, demarshal_get_city_id);
	add_query(GET_NEIGHBOURS, demarshal_get_neighbours);
	add_query(NEEDS, demarshal_needs);
	add_query(NULL_DRUGS_DEMAND, demarshal_null_drugs_demand);
	add_query(CLOSE_MAIN, demarshal_close_main);
	add_query(GET_CITY_CANT, demarshal_get_city_cant);
}
